#ifndef BA196C0D_24A3_4B79_905D_D8393332C7BD
#define BA196C0D_24A3_4B79_905D_D8393332C7BD

#include "functions.hpp"
#include <iostream>

enum class IntegralMethod {
  LeftRectangle,
  RightRectangle,
  MiddleRectangle,
  Trapezoid,
  Simpson
};

static std::string to_string(IntegralMethod method) {
  switch (method) {
  case IntegralMethod::LeftRectangle:
    return "Left Rectangle";
  case IntegralMethod::RightRectangle:
    return "Right Rectangle";
  case IntegralMethod::MiddleRectangle:
    return "Middle Rectangle";
  case IntegralMethod::Trapezoid:
    return "Trapezoid";
  case IntegralMethod::Simpson:
    return "Simpson";
  default:
    return "Unknown";
  }
}

static void print_all_methods() {
  for (auto method :
       {IntegralMethod::LeftRectangle, IntegralMethod::RightRectangle,
        IntegralMethod::MiddleRectangle, IntegralMethod::Trapezoid,
        IntegralMethod::Simpson}) {
    std::cout << static_cast<int>(method) << ": " << to_string(method)
              << std::endl;
  }
}

static bool validateIntegralMethod(int method) {
  return method >= 0 && method <= 4;
}

static void print_all_functions() {
  std::vector<Func *> functions = {
      Func::create_hyperbola(),  Func::create_linear(),
      Func::create_polynomial(), Func::create_scaled_logistic(),
      Func::create_sinus(),      Func::create_sqrt_hyperbola(),
  };
  sort(functions.begin(), functions.end(), [](Func const *f1, Func const *f2) {
    return f1->get_type() < f2->get_type();
  });
  for (auto func : functions) {
    std::cout << static_cast<int>(func->get_type()) << ": "
              << func->get_function_type() << " ["
              << func->get_function_representation() << "]" << std::endl;
  }
}

static bool validateFunctionType(int type) { return type >= 0 && type <= 5; }

#endif /* BA196C0D_24A3_4B79_905D_D8393332C7BD */
